/*
* Copyright 2017 Yonyou Auto Information Technology（Shanghai） Co., Ltd. All Rights Reserved.
*
* This software is published under the terms of the YONYOU Software
* License version 1.0, a copy of which has been included with this
* distribution in the LICENSE.txt file.
*
* @Project Name : marketing-common
*
* @File name : RequestLimitContract.java
*
* @Author : Administrator
*
* @Date : 2017年7月11日
*
----------------------------------------------------------------------------------
*     Date       Who       Version     Comments
* 1. 2017年7月11日    Administrator    1.0
*
*
*
*
----------------------------------------------------------------------------------
*/
	
package com.yonyou.gmmc.service.information.service;

import com.yonyou.gmmc.service.information.constant.RequestLimit;
import com.yonyou.gmmc.service.information.constant.RequestLimitException;
import com.yonyou.gmmc.service.information.model.TtBlackList;
import com.yonyou.gmmc.service.information.util.SpringUtil;

import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;  
import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;  
import java.util.Timer;  
import java.util.TimerTask;  

/**
*
* @author Administrator
* TODO description
* @date 2017年7月11日
*/

  
@Aspect  
@Component  
public class RequestLimitContract {  
    private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");  
    private Map<String, Integer> redisTemplate=new HashMap<String,Integer>();  
    @Before("within(@org.springframework.stereotype.Service *) && @annotation(limit)")  
    public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {  
        try {  
            Object[] args = joinPoint.getArgs();  
            HttpServletRequest request = null;  
            for (int i = 0; i < args.length; i++) {  
                if (args[i] instanceof HttpServletRequest) {  
                    request = (HttpServletRequest) args[i];  
                    break;  
                }  
            }  
            if (request == null) {  
                throw new RequestLimitException("方法中缺失HttpServletRequest参数");  
            }  
            InformationService informationService=(InformationService)SpringUtil.getBean("informationService");
            String ip = request.getLocalAddr();  
            String url = request.getRequestURL().toString();  
            String key = "req_limit_".concat(url).concat(ip); 
            List<TtBlackList> list = new ArrayList<TtBlackList>();
            list = informationService.findByIp(ip);
            if(list.size()==0){
                if(redisTemplate.get(key)==null || redisTemplate.get(key)==0){  
                    redisTemplate.put(key,1);  
                }else{  
                    redisTemplate.put(key,redisTemplate.get(key)+1);  
                }  
                int count = redisTemplate.get(key);  
                if (count > 0) {  
                    Timer timer= new Timer();  
                    TimerTask task  = new TimerTask(){    //创建一个新的计时器任务。  
                        @Override  
                        public void run() {  
                            redisTemplate.remove(key);  
                        }  
                    };  
                    timer.schedule(task, limit.time());  
                    //安排在指定延迟后执行指定的任务。task : 所要安排的任务。10000 : 执行任务前的延迟时间，单位是毫秒。  
                }  
                if (count > limit.count()) {  
//                    logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");  
                    TtBlackList blackList = new TtBlackList();
                    blackList.setIp(ip);
                    logger.info("加入黑名单的IP为："+blackList);
                    int i = informationService.addBlackList(blackList);
                    logger.info("黑名单表中新增了"+i+"条记录");
                    throw new RequestLimitException(ip);  
                }
            } else{
                logger.info("用户IP在黑名单中");  
                throw new RequestLimitException(ip);  
            }
        } catch (RequestLimitException e) {  
            throw e;  
        } catch (Exception e) {  
            logger.error("发生异常: ", e);  
        }  
    }  
}  
